/*
 * =====================================================================================
 *
 *       Filename:  Creature.cpp
 *
 *    Description:  Implementation of Craeture
 *
 *        Version:  1.0
 *        Created:  01/06/12 17:02:44
 *       Revision:  none
 *       Compiler:  g++
 *
 *         Author:  LittleQ Su (), 98703060@nccu.edu.tw
 *        Company:  National Chengchi University, The Department of Computer Science
 *
 * =====================================================================================
 */

#include "Creature.h"
#include "World.h"
#include "Goat.h"
#include "Grass.h"

Creature::Creature(void *world, int x, int y) {
    this -> x = x;
    this -> y = y;
    this -> _world = world; 
    this -> _id_word = NOONE;
    this -> _moved = false;
}

enum CREATURE_TYPE Creature::get_identify_word() const {
    return this -> _id_word;
}

int Creature::getAge() {
    return this -> _age;
}

void Creature::detectDead() {
    if ( _age >= _max_age ) {
        ((World*)_world) -> removeCreature(this->x, this->y);
    }
}

void Creature::genChild() {
    if ( _age < _gen_age[0] || _age > _gen_age[1] ) { return; }
    
    int new_x, new_y;
    do {
        new_x = this -> x + ((World*)_world)->getRandom(-1, 1);
        new_y = this -> y + ((World*)_world)->getRandom(-1, 1);

    } while ( new_x == 0 && new_y == 0 );

    if ( new_x < 0 || new_x > 34 || new_y < 0 || new_y > 19 ) {
        return;
    }

    enum CREATURE_TYPE origin = ((World*)_world) -> getCreature(new_x, new_y);

    if ( this->_id_word == GOAT ) {
        // Goat 
        if ( origin == GOAT ) { return; }
        if ( origin == GRASS ) {
            ((World*)_world)->removeCreature(new_x, new_y);
            ((Goat*)this)->addFood(5);
        }
        ((World*)_world)->addCreature(GOAT, new_x, new_y);
    } else if ( this->_id_word == GRASS) {
        // Grass
        if ( origin != NOONE ) {
            return;
        }
        ((World*)_world)->addCreature(GRASS, new_x, new_y);
    }
}

void Creature::action() {

}

bool Creature::getMoved() {
    return this -> _moved;
}
void Creature::setMoved(bool b) {
    this -> _moved = b;
}
